<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>语音合成服务</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 40px rgba(0,0,0,0.1);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }

        .header p {
            font-size: 1.1em;
            opacity: 0.9;
        }

        .content {
            padding: 40px;
        }

        .form-section {
            margin-bottom: 30px;
        }

        .form-section h3 {
            color: #333;
            margin-bottom: 15px;
            font-size: 1.3em;
            border-bottom: 2px solid #667eea;
            padding-bottom: 10px;
        }

        .form-group {
            margin-bottom: 20px;
        }

        .form-group label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #555;
        }

        .form-control {
            width: 100%;
            padding: 12px 15px;
            border: 2px solid #e1e5e9;
            border-radius: 10px;
            font-size: 16px;
            transition: all 0.3s ease;
        }

        .form-control:focus {
            outline: none;
            border-color: #667eea;
            box-shadow: 0 0 0 3px rgba(102, 126, 234, 0.1);
        }

        textarea.form-control {
            min-height: 120px;
            resize: vertical;
        }

        .form-row {
            display: grid;
            grid-template-columns: 1fr 1fr;
            gap: 20px;
        }

        .range-group {
            display: flex;
            align-items: center;
            gap: 15px;
        }

        .range-group input[type="range"] {
            flex: 1;
        }

        .range-value {
            min-width: 50px;
            text-align: center;
            font-weight: 600;
            color: #667eea;
        }

        .btn {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            border: none;
            padding: 15px 30px;
            border-radius: 10px;
            font-size: 16px;
            font-weight: 600;
            cursor: pointer;
            transition: all 0.3s ease;
            margin-right: 15px;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 10px 20px rgba(102, 126, 234, 0.3);
        }

        .btn:disabled {
            opacity: 0.6;
            cursor: not-allowed;
            transform: none;
        }

        .btn-secondary {
            background: #6c757d;
        }

        .btn-secondary:hover {
            box-shadow: 0 10px 20px rgba(108, 117, 125, 0.3);
        }

        .audio-section {
            margin-top: 30px;
            padding: 30px;
            background: #f8f9fa;
            border-radius: 15px;
            text-align: center;
        }

        .audio-player {
            width: 100%;
            max-width: 500px;
            margin: 20px auto;
        }

        .status {
            padding: 15px;
            border-radius: 10px;
            margin: 20px 0;
            font-weight: 600;
        }

        .status.success {
            background: #d4edda;
            color: #155724;
            border: 1px solid #c3e6cb;
        }

        .status.error {
            background: #f8d7da;
            color: #721c24;
            border: 1px solid #f5c6cb;
        }

        .status.info {
            background: #d1ecf1;
            color: #0c5460;
            border: 1px solid #bee5eb;
        }

        .loading {
            display: none;
            text-align: center;
            padding: 20px;
        }

        .spinner {
            border: 4px solid #f3f3f3;
            border-top: 4px solid #667eea;
            border-radius: 50%;
            width: 40px;
            height: 40px;
            animation: spin 1s linear infinite;
            margin: 0 auto 15px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }

        .checkbox-group {
            display: flex;
            gap: 20px;
            margin-top: 10px;
        }

        .checkbox-item {
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .checkbox-item input[type="checkbox"] {
            width: 18px;
            height: 18px;
        }

        @media (max-width: 768px) {
            .form-row {
                grid-template-columns: 1fr;
            }
            
            .content {
                padding: 20px;
            }
            
            .header h1 {
                font-size: 2em;
            }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🎵 语音合成服务</h1>
            <p>将文本转换为自然流畅的语音</p>
        </div>

        <div class="content">
            <form id="ttsForm">
                <!-- 基础设置 -->
                <div class="form-section">
                    <h3>📝 文本内容</h3>
                    <div class="form-group">
                        <label for="text">要转换的文本内容 *</label>
                        <textarea 
                            id="text" 
                            name="text" 
                            class="form-control" 
                            placeholder="请输入要转换为语音的文本内容（最多10000个字符）"
                            required
                            maxlength="10000"
                        ></textarea>
                        <small style="color: #666; margin-top: 5px; display: block;">
                            字符数: <span id="charCount">0</span>/10000
                        </small>
                    </div>
                </div>

                <!-- 模型和格式设置 -->
                <div class="form-section">
                    <h3>⚙️ 模型和格式设置</h3>
                    <div class="form-row">
                        <div class="form-group">
                            <label for="model">语音模型</label>
                            <select id="model" name="model" class="form-control">
                                <option value="sambert-zhinan-v1">知楠（广告男声，48k，中文+英文）</option>
                                <option value="sambert-zhiqi-v1">知琪（温柔女声，48k，中文+英文）</option>
                                <option value="sambert-zhichu-v1">知厨（舌尖男声，新闻播报，48k，中文+英文，推荐）</option>
                                <option value="sambert-zhide-v1">知德（新闻男声，新闻播报，48k，中文+英文）</option>
                                <option value="sambert-zhijia-v1">知佳（标准女声，新闻播报，48k，中文+英文）</option>
                                <option value="sambert-zhiru-v1">知茹（新闻女声，新闻播报，48k，中文+英文）</option>
                                <option value="sambert-zhiqian-v1">知倩（资讯女声，配音解说/新闻播报，48k，中文+英文）</option>
                                <option value="sambert-zhixiang-v1">知祥（磁性男声，配音解说，48k，中文+英文）</option>
                                <option value="sambert-zhiwei-v1">知薇（萝莉女声，产品简介，48k，中文+英文）</option>
                                <option value="sambert-zhihao-v1">知浩（咨询男声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhijing-v1">知婧（严厉女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiming-v1">知茗（诙谐男声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhimo-v1">知墨（情感男声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhina-v1">知娜（浙普女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhishu-v1">知树（资讯男声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhistella-v1">知莎（知性女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiting-v1">知婷（电台女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhixiao-v1">知笑（资讯女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiya-v1">知雅（严厉女声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiye-v1">知晔（青年男声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiying-v1">知颖（软萌童声，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiyuan-v1">知媛（知心姐姐，通用，16k，中文+英文）</option>
                                <option value="sambert-zhiyue-v1">知悦（温柔女声，客服，16k，中文+英文）</option>
                                <option value="sambert-zhigui-v1">知柜（直播女声，产品简介，16k，中文+英文）</option>
                                <option value="sambert-zhishuo-v1">知硕（自然男声，数字人，16k，中文+英文）</option>
                                <option value="sambert-zhimiao-emo-v1">知妙（多情感女声，产品简介/数字人/直播，16k，中文+英文）</option>
                                <option value="sambert-zhimao-v1">知猫（直播女声，产品简介/配音解说/数字人/直播，16k，中文+英文）</option>
                                <option value="sambert-zhilun-v1">知伦（悬疑解说，配音解说，16k，中文+英文）</option>
                                <option value="sambert-zhifei-v1">知飞（激昂解说，配音解说，16k，中文+英文）</option>
                                <option value="sambert-zhida-v1">知达（标准男声，新闻播报，16k，中文+英文）</option>
                                <option value="sambert-camila-v1">Camila（西班牙语女声，16k，西班牙语）</option>
                                <option value="sambert-perla-v1">Perla（意大利语女声，16k，意大利语）</option>
                                <option value="sambert-indah-v1">Indah（印尼语女声，16k，印尼语）</option>
                                <option value="sambert-clara-v1">Clara（法语女声，16k，法语）</option>
                                <option value="sambert-hanna-v1">Hanna（德语女声，16k，德语）</option>
                                <option value="sambert-beth-v1">Beth（咨询女声，通用，16k，美式英文）</option>
                                <option value="sambert-betty-v1">Betty（客服女声，通用，16k，美式英文）</option>
                                <option value="sambert-cally-v1">Cally（自然女声，通用，16k，美式英文）</option>
                                <option value="sambert-cindy-v1">Cindy（对话女声，通用，16k，美式英文）</option>
                                <option value="sambert-eva-v1">Eva（陪伴女声，通用，16k，美式英文）</option>
                                <option value="sambert-donna-v1">Donna（教育女声，通用，16k，美式英文）</option>
                                <option value="sambert-brian-v1">Brian（客服男声，通用，16k，美式英文）</option>
                                <option value="sambert-waan-v1">Waan（泰语女声，16k，泰语）</option>
                            </select>
                        </div>
                        <div class="form-group">
                            <label for="format">音频格式</label>
                            <select id="format" name="format" class="form-control">
                                <option value="WAV">WAV (无损)</option>
                                <option value="MP3">MP3 (压缩)</option>
                                <option value="PCM">PCM (原始)</option>
                            </select>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="sampleRate">采样率 (Hz)</label>
                        <select id="sampleRate" name="sampleRate" class="form-control">
                            <option value="8000">8000 Hz</option>
                            <option value="16000" selected>16000 Hz (推荐)</option>
                            <option value="22050">22050 Hz</option>
                            <option value="44100">44100 Hz</option>
                            <option value="48000">48000 Hz</option>
                        </select>
                    </div>
                </div>

                <!-- 语音参数设置 -->
                <div class="form-section">
                    <h3>🎚️ 语音参数调节</h3>
                    <div class="form-row">
                        <div class="form-group">
                            <label for="volume">音量</label>
                            <div class="range-group">
                                <input type="range" id="volume" name="volume" min="0" max="100" value="50" class="form-control">
                                <span class="range-value" id="volumeValue">50</span>
                            </div>
                        </div>
                        <div class="form-group">
                            <label for="rate">语速</label>
                            <div class="range-group">
                                <input type="range" id="rate" name="rate" min="5" max="20" value="10" step="1" class="form-control">
                                <span class="range-value" id="rateValue">1.0</span>
                            </div>
                        </div>
                    </div>
                    <div class="form-group">
                        <label for="pitch">语调</label>
                        <div class="range-group">
                            <input type="range" id="pitch" name="pitch" min="5" max="20" value="10" step="1" class="form-control">
                            <span class="range-value" id="pitchValue">1.0</span>
                        </div>
                    </div>
                </div>

                <!-- 高级选项 -->
                <div class="form-section">
                    <h3>🔧 高级选项</h3>
                    <div class="checkbox-group">
                        <div class="checkbox-item">
                            <input type="checkbox" id="enableWordTimestamp" name="enableWordTimestamp">
                            <label for="enableWordTimestamp">启用词级时间戳</label>
                        </div>
                        <div class="checkbox-item">
                            <input type="checkbox" id="enablePhonemeTimestamp" name="enablePhonemeTimestamp">
                            <label for="enablePhonemeTimestamp">启用音素级时间戳</label>
                        </div>
                        <div class="checkbox-item">
                            <input type="checkbox" id="streamMode" name="streamMode">
                            <label for="streamMode">流式模式</label>
                        </div>
                    </div>
                </div>

                <!-- 操作按钮 -->
                <div class="form-section">
                    <button type="submit" id="synthesizeBtn" class="btn">
                        🎵 开始合成
                    </button>
                    <button type="button" id="resetBtn" class="btn btn-secondary">
                        🔄 重置参数
                    </button>
                </div>
            </form>

            <!-- 加载状态 -->
            <div id="loading" class="loading">
                <div class="spinner"></div>
                <p>正在合成语音，请稍候...</p>
            </div>

            <!-- 状态信息 -->
            <div id="status" class="status" style="display: none;"></div>

            <!-- 音频播放区域 -->
            <div id="audioSection" class="audio-section" style="display: none;">
                <h3>🎧 合成结果</h3>
                <audio id="audioPlayer" class="audio-player" controls>
                    您的浏览器不支持音频播放
                </audio>
                <div style="margin-top: 20px;">
                    <button id="downloadBtn" class="btn">💾 下载音频</button>
                    <button id="playAgainBtn" class="btn btn-secondary">🔄 重新播放</button>
                    <a href="/api/upload/page" id="uploadAudioBtn" class="btn" style="margin-left:10px;" target="_blank">⬆️ 上传音频</a>
                </div>
            </div>
        </div>
    </div>

    <script>
        // 字符计数
        document.getElementById('text').addEventListener('input', function() {
            const count = this.value.length;
            document.getElementById('charCount').textContent = count;
        });

        // 范围滑块值显示
        function updateRangeValue(rangeId, valueId, multiplier = 1) {
            const range = document.getElementById(rangeId);
            const value = document.getElementById(valueId);
            range.addEventListener('input', function() {
                value.textContent = (this.value * multiplier / 10).toFixed(1);
            });
        }

        updateRangeValue('volume', 'volumeValue', 1);
        updateRangeValue('rate', 'rateValue', 1);
        updateRangeValue('pitch', 'pitchValue', 1);

        // 表单提交
        document.getElementById('ttsForm').addEventListener('submit', async function(e) {
            e.preventDefault();
            
            const formData = new FormData(this);
            const requestData = {
                text: formData.get('text'),
                model: formData.get('model'),
                format: formData.get('format'),
                sampleRate: parseInt(formData.get('sampleRate')),
                volume: parseInt(formData.get('volume')),
                rate: parseFloat(formData.get('rate')) / 10,
                pitch: parseFloat(formData.get('pitch')) / 10,
                enableWordTimestamp: formData.get('enableWordTimestamp') === 'on',
                enablePhonemeTimestamp: formData.get('enablePhonemeTimestamp') === 'on',
                streamMode: formData.get('streamMode') === 'on'
            };

            // 显示加载状态
            document.getElementById('loading').style.display = 'block';
            document.getElementById('status').style.display = 'none';
            document.getElementById('audioSection').style.display = 'none';
            document.getElementById('synthesizeBtn').disabled = true;

            try {
                const response = await fetch('/api/tts/synthesize', {
                    method: 'POST',
                    headers: {
                        'Content-Type': 'application/json'
                    },
                    body: JSON.stringify(requestData)
                });

                if (response.ok) {
                    // 获取音频数据
                    const audioBlob = await response.blob();
                    const audioUrl = URL.createObjectURL(audioBlob);
                    
                    // 设置音频播放器
                    const audioPlayer = document.getElementById('audioPlayer');
                    audioPlayer.src = audioUrl;
                    
                    // 显示成功状态
                    showStatus('语音合成成功！', 'success');
                    document.getElementById('audioSection').style.display = 'block';
                    
                    // 设置下载按钮
                    document.getElementById('downloadBtn').onclick = function() {
                        const link = document.createElement('a');
                        link.href = audioUrl;
                        link.download = `tts_${new Date().toISOString().slice(0,19).replace(/:/g,'-')}.${requestData.format.toLowerCase()}`;
                        link.click();
                    };
                    
                    // 重新播放按钮
                    document.getElementById('playAgainBtn').onclick = function() {
                        audioPlayer.currentTime = 0;
                        audioPlayer.play();
                    };
                    
                } else {
                    const errorData = await response.json();
                    showStatus(`合成失败: ${errorData.message}`, 'error');
                }
            } catch (error) {
                showStatus(`请求失败: ${error.message}`, 'error');
            } finally {
                document.getElementById('loading').style.display = 'none';
                document.getElementById('synthesizeBtn').disabled = false;
            }
        });

        // 重置按钮
        document.getElementById('resetBtn').addEventListener('click', function() {
            document.getElementById('ttsForm').reset();
            document.getElementById('charCount').textContent = '0';
            document.getElementById('volumeValue').textContent = '50';
            document.getElementById('rateValue').textContent = '1.0';
            document.getElementById('pitchValue').textContent = '1.0';
            document.getElementById('status').style.display = 'none';
            document.getElementById('audioSection').style.display = 'none';
        });

        // 显示状态信息
        function showStatus(message, type) {
            const status = document.getElementById('status');
            status.textContent = message;
            status.className = `status ${type}`;
            status.style.display = 'block';
        }

        // 页面加载完成后的初始化
        document.addEventListener('DOMContentLoaded', function() {
            // 设置默认值
            document.getElementById('charCount').textContent = '0';
        });
    </script>
</body>
</html> 